﻿using System;
using System.Windows;
using JellystonePark.Desktop.Data;
using JellystonePark.Model;
using JellystonePark.JellystoneWPF.ViewModel;
using JellystonePark.JellystoneWPF.View;

namespace JellystonePark.JellystoneWPF
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        #region Fields

        private SetupViewModel _setupViewmodel;
        private SetupWindow _setupView;
        private JellystoneModel _gameModel;
        private JellystoneViewModel _gameViewmodel;
        private JellystoneWindow _gameView;
        private bool _initialized;

        #endregion

        #region Protected event handlers

        /// <summary>
        /// Alkalmazás indításának eseménykezelője.
        /// </summary>
        /// <param name="e">Játék indításához szükséges paramétereket átadó eseményargumentum.</param>
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
            _initialized = false;
            
            _gameView = new JellystoneWindow();

            _gameModel = new JellystoneModel();
            _gameModel.NewGame(JellystoneFileManager.LoadResource(JellystonePark.Desktop.Data.Resources.DefaultLevels));
            _gameModel.LevelOver += _model_LevelOver;
            _gameModel.GameOver += _model_GameOver;

            _gameViewmodel = new JellystoneViewModel(_gameModel);
            _gameViewmodel.LoadLevels += _viewmodelJellystone_LoadLevels;
            _gameViewmodel.NewGame += _viewmodelJellystone_NewGame;
            _gameViewmodel.Toggled += _viewmodelJellystone_Toggled;
            _gameViewmodel.SteppedDown += _viewmodelJellystone_SteppedDown;
            _gameViewmodel.SteppedLeft += _viewmodelJellystone_SteppedLeft;
            _gameViewmodel.SteppedRight += _viewmodelJellystone_SteppedRight;
            _gameViewmodel.SteppedUp += _viewmodelJellystone_SteppedUp;

            _gameView.DataContext = _gameViewmodel;
            _gameView.Closing += _view_Closing;
            _gameView.Show();
        }

        #endregion

        #region JellystoneModel event handlers

        void _model_GameOver(object sender, JellystoneResultEventArgs e)
        {
            MessageBox.Show(_gameModel.Player.Name + " eredményei:" + Environment.NewLine +
                "Lépések száma: " + e.Steps.ToString() + Environment.NewLine +
                "Összes játékidő: " + TimeSpan.FromSeconds(e.TimeElapsed).ToString("g"), "A játék véget ért", MessageBoxButton.OK, MessageBoxImage.Information);
            _gameModel.RestartGame();
            _gameViewmodel.SetupTable();            
        }

        void _model_LevelOver(object sender, JellystoneResultEventArgs e)
        {
            if (e.IsWon)
            {
                JellystoneFileManager.PlaySound(JellystonePark.Desktop.Data.Resources.WinSound);
                MessageBox.Show("Nyertél!", (_gameModel.CurrentLevel + 1).ToString() + ". szint", MessageBoxButton.OK, MessageBoxImage.Information);
                _gameModel.NextLevel();
                _gameViewmodel.SetupTable();
            }
            else
            {
                JellystoneFileManager.PlaySound(JellystonePark.Desktop.Data.Resources.WinSound);
                MessageBox.Show("Vesztettél!", (_gameModel.CurrentLevel + 1).ToString() + ". szint", MessageBoxButton.OK, MessageBoxImage.Information);
                _gameModel.RestartLevel();
                _gameViewmodel.SetupTable();
            }
        }

        #endregion

        #region JellystoneViewModel event handlers

        void _viewmodelJellystone_SteppedUp(object sender, EventArgs e)
        {
            _gameModel.StepUp();
        }

        void _viewmodelJellystone_SteppedRight(object sender, EventArgs e)
        {
            _gameModel.StepRight();
        }

        void _viewmodelJellystone_SteppedLeft(object sender, EventArgs e)
        {
            _gameModel.StepLeft();
        }

        void _viewmodelJellystone_SteppedDown(object sender, EventArgs e)
        {
            _gameModel.StepDown();
        }

        void _viewmodelJellystone_Toggled(object sender, EventArgs e)
        {
            if (_initialized)
                _gameModel.Toggle();
            else
                MessageBox.Show("Először kezdj új játékot!", "Hiba!", MessageBoxButton.OK, MessageBoxImage.Error);
        }

        void _viewmodelJellystone_NewGame(object sender, EventArgs e)
        {
            _gameModel.Pause();
            SetupGame();
        }

        void _viewmodelJellystone_LoadLevels(object sender, EventArgs e)
        {
            _gameModel.Pause();
            if (_initialized)
                LoadExternLevels();
            else
                SetupGame();
        }

        #endregion

        #region JellystoneView event handlers

        void _view_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            _gameModel.Pause();
            if (e.Cancel = !IsClosing())
                _gameModel.Continue();
            //else
            //    Application.Current.Shutdown();
        }

        #endregion

        #region Private methods

        private bool IsClosing()
        {
            return MessageBox.Show("Biztos, hogy ki akarsz lépni?", "Maci Laci V2", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes;
        }

        /// <summary>
        /// Pályacsomag betöltése külső fájlból.
        /// </summary>
        /// <returns></returns>
        private bool LoadExternLevels()
        {
            try
            {
                Microsoft.Win32.OpenFileDialog oDialog = new Microsoft.Win32.OpenFileDialog();
                oDialog.Title = "Pályacsomag betöltése";
                oDialog.Filter = "Jellystone pályacsomag fájl|*.jlv";
                if (true == oDialog.ShowDialog())
                {
                    _gameModel.NewGame(JellystoneFileManager.LoadFile(oDialog.FileName));
                    return true;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("A fájl betöltése sikertelen volt!" + Environment.NewLine + ex.Message, "Maci Laci V2", MessageBoxButton.OK, MessageBoxImage.Error);
            }
            return false;
        }

        /// <summary>
        /// Beállítások dialógusablak megjelenítése és játék inicializálása.
        /// </summary>
        private void SetupGame()
        {
            _setupViewmodel = new SetupViewModel();

            _setupView = new SetupWindow();
            _setupView.DataContext = _setupViewmodel;
            _setupView.ShowDialog();

            if (_setupView.DialogResult.HasValue) {
                if (_setupView.DialogResult.Value)
                {
                    _gameModel.Player = new JellystonePlayer(_setupViewmodel.PlayerName);
                    _gameModel.Difficulty = _setupViewmodel.Difficulty;
                    _initialized = true;
                    if (_setupViewmodel.IsDefaultLevels)
                        _gameModel.NewGame(JellystoneFileManager.LoadResource(JellystonePark.Desktop.Data.Resources.DefaultLevels));
                    else
                        LoadExternLevels();
                }
                else
                {
                    MessageBox.Show("A játkos neve nem maradhat üresen!", "Hiba", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
        }

        #endregion
    }
}
